package com.weilele.mvvm.view

import android.animation.ValueAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.core.animation.doOnEnd
import androidx.core.view.ViewCompat

/**
 * 只是对[BaseNestedScrollingParentLayout]的一个是用案例
 * 根据需求自己封装
 */
open class SwipeVerticalLayout : BaseNestedScrollingParentLayout {
    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    /**
     * 动画结束后回调
     */
    private var endAction: Function1<SwipeVerticalLayout, Unit>? = null

    /**
     * 位移动画
     */
    private val stopAnim by lazy {
        ValueAnimator.ofInt(0, 0).apply {
            addUpdateListener {
                realOffset = it.animatedValue as Int
                onNotifyOffsetChange(realOffset, true)
            }
            doOnEnd {
                endAction?.invoke(this@SwipeVerticalLayout)
                endAction = null
            }
        }
    }

    /***
     * 当前view的偏移量
     */
    private var realOffset = 0

    override fun onStartNestedScroll(child: View, target: View, axes: Int, type: Int): Boolean {
        if (stopAnim.isRunning) {
            return false
        }
        if (type != ViewCompat.TYPE_TOUCH) {
            return false
        }
        return super.onStartNestedScroll(child, target, axes, type)
    }

    override fun onNestedPreScroll(target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) {
        super.onNestedPreScroll(target, dx, dy, consumed, type)
        checkPreScroll(target, dy, consumed)
    }

    private fun checkPreScroll(target: View, dy: Int, consumed: IntArray) {
        if (dy == 0 || realOffset == 0) {
            return
        }
        //realOffset不为0，判断发生了位移
        val oldRealOffset = realOffset
        when {
            oldRealOffset > 0 -> {
                val off = realOffset + dy
                if (off > 0) {//需要消耗完所有滚动距离
                    consumed[1] = dy
                    realOffset += dy
                } else {//只需要消耗realOffset的值
                    consumed[1] = -oldRealOffset
                    realOffset = 0
                }
            }
            oldRealOffset < 0 -> {
                val off = realOffset + dy
                if (off < 0) {//需要消耗完所有滚动距离
                    consumed[1] = dy
                    realOffset += dy
                } else {//只需要消耗realOffset的值
                    consumed[1] = -oldRealOffset
                    realOffset = 0
                }
            }
        }
        if (oldRealOffset != realOffset) {
            onNotifyOffsetChange(realOffset, false)
        }
    }

    override fun onNestedScroll(
        target: View/*滚动的子view*/,
        dxConsumed: Int/*子view已经消耗*/,
        dyConsumed: Int/*子view已经消耗*/,
        dxUnconsumed: Int/*子view未消耗*/,
        dyUnconsumed: Int/*子view未消耗*/,
        type: Int,
        consumed: IntArray
    ) {
        realOffset += dyUnconsumed
        onNotifyOffsetChange(realOffset, false)
    }

    override fun onStopNestedScroll(target: View, type: Int) {
        super.onStopNestedScroll(target, type)
        if (type == ViewCompat.TYPE_TOUCH) {
            animReset()
        }
    }

    /**
     * 通过动画，重置到endValue位置
     */
    fun animReset(
        endValue: Int = 0,
        duration: Long = 200L,
        animEndAction: Function1<SwipeVerticalLayout, Unit>? = null
    ) {
        if (stopAnim.isRunning) {
            return
        }
        if (realOffset != endValue) {
            this.endAction = animEndAction
            stopAnim.setIntValues(realOffset, endValue)
            stopAnim.duration = duration
            stopAnim.start()
        }
    }

    /**
     * 清除endAction的监听
     */
    fun clearAnimEndAction() {
        this.endAction = null
    }

    /**
     * 距离发生变化
     */
    open fun onNotifyOffsetChange(realOffset: Int, isAnim: Boolean) {
        getChildAt(0).translationY = -realOffset * 0.2f
    }
}